package dimensional.traveler.client.screens.characterclasschooser;

import java.util.LinkedList;
import java.util.List;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import dimensional.traveler.client.mvc.ControlledComposite;
import dimensional.traveler.client.mvc.MediatedController;
import dimensional.traveler.shared.Settings;
import dimensional.traveler.shared.model.CharacterClassDTO;

public class CharacterClassChooserScreen extends ControlledComposite implements ClickHandler {

	private static CharacterClassChooserScreenUiBinder uiBinder = GWT.create(CharacterClassChooserScreenUiBinder.class);

	interface CharacterClassChooserScreenUiBinder extends UiBinder<Widget, CharacterClassChooserScreen> {
	}

	@UiField
	FlowPanel cellListContainer;
	@UiField
	Image characterClassPicture;
	@UiField
	HTML characterClassDescription;
	@UiField
	Button backButton;
	@UiField
	Button nextButton;

	private String selectedCharacterId;
	private List<CharacterClassDTO> characterClasses= new LinkedList<CharacterClassDTO>();
	private CharacterClassChooserController controller = new CharacterClassChooserController();
	private CharacterClassCellList cellList;

	public CharacterClassChooserScreen() {
		initWidget(uiBinder.createAndBindUi(this));
		createCellList();
		addButtonEvents();
		setupController();
	}

	private void createCellList() {
		cellList = new CharacterClassCellList();
		cellListContainer.add(cellList);
	}

	private void addButtonEvents() {
		backButton.addClickHandler(this);
		nextButton.addClickHandler(this);
	}
	
	private void setupController() {
		this.addAttachHandler(controller);
	}

	public void addCharacterClasses(List<CharacterClassDTO> characterClasses) {
		this.characterClasses.addAll(characterClasses);
		cellList.updateWithValues();
	}
	
	private class CharacterClassCell extends AbstractCell<CharacterClassDTO> {
		@Override
		public void render(Context context, CharacterClassDTO characterClass, SafeHtmlBuilder sb) {
			if (characterClass != null) {
				sb.appendHtmlConstant("<div style=\"padding: 5px 0;\">");
				sb.appendEscaped(characterClass.getName());
				sb.appendHtmlConstant("</div>");
			}
		}
	}

	private class CharacterClassCellList extends CellList<CharacterClassDTO> {

		private SingleSelectionModel<CharacterClassDTO> selectionModel;

		public CharacterClassCellList() {
			super(new CharacterClassCell());
			setupSelectionModel();
		}

		private void setupSelectionModel() {
			selectionModel = new SingleSelectionModel<CharacterClassDTO>();
			this.setSelectionModel(selectionModel);
			selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
				public void onSelectionChange(SelectionChangeEvent event) {
					CharacterClassDTO selected = selectionModel.getSelectedObject();
					if (selected != null) {
						CharacterClassChooserScreen.this.updateWith(selected);
					}
				}
			});
			this.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		}

		public void updateWithValues() {
			setCellData();
			selectFirstCell();
		}

		private void setCellData() {
			this.setRowCount(CharacterClassChooserScreen.this.characterClasses.size(), true);
			this.setRowData(CharacterClassChooserScreen.this.characterClasses);
		}

		private void selectFirstCell() {
			if (!CharacterClassChooserScreen.this.characterClasses.isEmpty())
				selectionModel.setSelected(CharacterClassChooserScreen.this.characterClasses.get(0), true);
		}

	}

	protected void updateWith(CharacterClassDTO selected) {
		setImageForCharacterClass(selected);
		characterClassDescription.setHTML(selected.getDescription() + "<br/>" + selected.getFactionDescription());
		selectedCharacterId = selected.getId();
		nextButton.setEnabled(selected.isEnabled());
	}

	private void setImageForCharacterClass(CharacterClassDTO selected) {
		if (!Settings.USE_PLACEHOLDERS) {
			characterClassPicture.setUrl("images/characters/" + selected.getId() + ".jpg");
		}
	}

	@Override
	public void onClick(ClickEvent event) {
		if (event.getSource() == backButton) {
			controller.back();
		} else if (event.getSource() == nextButton) {
			controller.startTutorial(selectedCharacterId);
		}
	}

	@Override
	public MediatedController getController() {
		return controller;
	}

}
